
int switches;
byte bar_count = 0;
void loop()
{

  // *******************Code to handle input switches and light LED's************************* 
  //switch positions on pedalboard:
  //1  5  13  12  8  4  0
  //3  7  15  14  10  6  2
  //Note: there is no LED for 1,3,9,11 B00001111 turns off LED's - no switch in position 9, 11


  PORTF = strobe[zcount];                //write to matrix
  for (i = 1 ; i <=2; i++) {       //small delay, delay function doesn't work right, prolly a interrupt conflict
  }

  switchin = PINK;   //read input port

  switchin = switchin & B00001111;   //mask lower nibble as we are using some higher bits for rotary selector switch


  for (i = 0; i < 16; i++)   {          // priority flash checks all keys
    if (light_led[i] == true)   
      flash_LED(i);
  }
  for (i = 0; i < 16; i++)   {          //will flash on utility mode one key "outstanding" at a time.... 
    if (blink_led[i] == true && blink_disable == false) {
      blink_LED(i);
      break;
    }
  }

  if (switchin != B00001111 && keypress == false) {          //check for keypress - a low bit
    keypress = true;
    last_keypress = millis();
    switch (switchin) {              //identify swicth that was pressed update "swnum"
    case B00001110:
      swnum = 0 + zcount;
      light_led[swnum] = true; 
      switch (swnum) {
      case 0:            //set upper offset utility function
        Set_Upper = true;
        blink_led[0] = true;
        swnum = 9;             
        break;
      case 1:      //stop midi clock output
        midi_clock_flag = false;
        count_out_sync = 0;
        Serial3.print(midi_stop, BYTE);
        break;
      case 2:          //set lower offset utility function 
        Set_Lower = true;
        blink_led[2] = true;
        swnum = 9;
        break;
      case 3:                              //start midi clock output only if midi is not already running
        if (midi_clock_flag == false) {
          start_flag = true;
          midi_clock_flag = true;
        }
        break;
      }
      break;
    case B00001101:
      swnum = 4 + zcount;
      light_led[swnum] = true;  
      switch (swnum) {
      case 4:   //*************upper button channel 4*****************
        Upper_Button(3,4,4);
        break;
      case 5:
        if (midi_button_1 == false) {        //set flag to avoid multiple identical midi messages
          MIDIcntrl(0xb0, MIDIcc[4], 127); 
          midi_button_1 = true;
        }        
        break;
      case 6:   //**********lower button channel 4*************
        Lower_Button(3,4,6); 
        break;
      case 7:
        if (midi_button_3 == false) {          //set flag to avoid multiple identical midi messages
          MIDIcntrl(0xb0, MIDIcc[5], 127); 
          midi_button_3 = true;
        } 
        break;
      }    
      break;
    case B00001011:
      swnum = 8 + zcount;
      light_led[swnum] = true;  
      switch (swnum) {
      case 8:  //************upper button channel 3*************
        Upper_Button(2,3,8);
        break;
      case 10:  //************lower button channel 3*************
        Lower_Button(2,3,10);
        break;
      }
      break;
    case B00000111:
      swnum = 12 + zcount;
      light_led[swnum] = true;  
      switch (swnum) {
      case 12:   //**************upper button channel 2***************
        Upper_Button(1,2,12);
        break;
      case 13:   //*************upper button channel 1*****************
        Upper_Button(0,1,13);
        break;
      case 14:  //***************lower button channel 2***************
        Lower_Button(1,2,14);
        break;
      case 15:  //******************lower button channel 1*****************
        Lower_Button(0,1,15);
        break;
      }      
      break;  
    }  
  } //end of main "if" for reading buttons

  //  for (i = 0; i < 16; i++)   {          // priority flash checks all keys  good place here for LED stuff if we have two instances..

  //    if (light_led[i] == true)   
  //      flash_LED(i);
  //  }
  //  for (i = 0; i < 16; i++)   {          //will flash on utility mode one key "outstanding" at a time.... 
  //    if (blink_led[i] == true && blink_disable == false) {
  //      blink_LED(i);
  //      break;
  //    }
  //  }



  //************************* tap tempo code*****************************



  slowState = digitalRead(A_SW);
  fastState = digitalRead(B_SW);

  // if slower button (A_SW) pressed, call function to increase count of tap registers || slow DOWN ||
  if( slowState == LOW && slowState != lastslowState && fastState == HIGH)
  {
    slowerTap(); /* we got a HIGH-LOW transitionon only the A switch, call slowerTap function */
    disp_BPM();
  }
  // if faster button pressed (B_SW), call function to decrease count of tap registers || speed UP || 
  else if( fastState == LOW && fastState != lastfastState && slowState == HIGH )
  {
    fasterTap(); /* we got a HIGH-LOW transition, call our tap() function */
    disp_BPM();
  }
  else if(  slowState == LOW && fastState == LOW && slowState != lastslowState )  
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
    // disp_BPM();
  }

  lastfastState = fastState; /* keep track of the state */
  lastslowState = slowState; /* keep track of the state */

  /* check for timer timeout  - only using this for blinking lLED during tap temp read and we disable wavetable blinks*/
  if( millis() >= timeoutTime )
  {
    /* timeout happened.  clock tick! */
    indicatorTimeout = millis() + 40;  /* this sets the time when LED goes off */
    /* and reschedule the timer to keep the pace */
    rescheduleTimer();
  }

  /* display the tap blink  LED */
  if (inhibit_LED == true) {
    if( millis() < indicatorTimeout) {   //this is active when reading BPM and down't want distracting wavetable blinks 
      digitalWrite( wave_led_pin, HIGH );                        //at another tempo
    }
    else {
      digitalWrite( wave_led_pin, LOW );
    }
  }

  /**********************************************************   
   *                      MIDI tap IN                     *   
   **********************************************************/
  //always execute - data is read in ISR for improved timing accuracy

  //  if(data == midi_start ) {
  //    play_flag = 1;
  //  }
  if (data == midi_continue) {
    play_flag = 1;
  }
  else if(data == midi_stop) {
    play_flag = 0;
    midi_ticks = 0;
    count_sync = 0;
    disp_BPM();
  }
  if (midi_tap == true) {    //reached the # of ticks 
    midi_tap = false;
    tap();
  }
  if (subdivide == true) {     //we are synched, read input beat selector switch
    subdivide = false;
    subdivide_tap();
  }




  //  if(Serial3.available() > 0) {
  //    data = Serial3.read();
  //    if(data == midi_start ) {
  //      play_flag = 1;
  //    }
  //
  //    else if (data == midi_continue) {
  //      play_flag = 1;
  //    }
  //    else if(data == midi_stop) {
  //      play_flag = 0;
  //      disp_BPM();
  //    }
  //    else if((data == midi_clock) && (play_flag == 1)) {
  //      Sync();       //we have a valid midi clock tick, count them!
  //    }
  //  }



  //****************functions once per loop*****************************


  //**************let there be LED light*******************   

  //  for (i = 0; i < 16; i++)   {          // priority flash checks all keys  LED stuff doesn't work well here, 
  //    if (light_led[i] == true)           //needs to be at tp of loop
  //      flash_LED(i);
  //  }
  //  for (i = 0; i < 16; i++)   {          //will flash on utility mode one key "outstanding" at a time.... 
  //    if (blink_led[i] == true && blink_disable == false) {
  //      blink_LED(i);
  //      break;
  //    }
  //  }

  if (switchin != B00001101 && zcount == 3 && midi_button_3 == true) {      //clear the midi controller (sustain) flag when switch has just been released                                                
    MIDIcntrl(0xb0, MIDIcc[5], 0);
    midi_button_3 = false;  
  }  

  if (millis() - last_keypress > 400 && keypress == true) {      //debounce and avoid repeating loop
    keypress = false;

    if (midi_button_1 == true)  {                                //clear the midi controller  flag 
      //     MIDIcntrl(0xb0, MIDIcc[4], 0);
      midi_button_1 = false;  
    }
    //  Serial.print(swnum);
  }

  phaseDelta = BPM >> 2; // divide by 4 to get BPM to Hz for the lookup table ... needed in loop 

  if (zcount == 1) {   //reduce the writes to the bargraph routinen stagger with midi writes
    bar_count = bar_count + 1;
    if (bar_count > 3)
      bar_count = 0; 
    if (wave_channel[bar_count] == 0) 
      BARGRAPH (bar_count);
  }
  if (MIDIVout[bar_count] == true && zcount == 3)  {   //try this to reduce serial writes per loop
    int MIDIVal = Vout[bar_count]/2;
    MIDIcntrl(0xb0, MIDIcc[bar_count], MIDIVal);      // to midi channel 1, cc number from array
    MIDIVout[bar_count] = false;
  }

  Offset_Adjust();                            // function to write offsets once per loop

  // **************counter for once - per loop functions 

  zcount = zcount++;        //increment stobe lines to check for keypress once though each loop to spread out load
  if (zcount > 3) {
    zcount = 0;
  }

}  //loop end 




//      case 4:   //*************upper button channel 4*****************
//      Upper_Button(3,4,4);
//        if (HOLD_FLAG[3] == false && Set_Lower == false && Set_Upper == false) {  // no hold or offset functions, then lock
//          Serial2.print("?y3?x00");
//          Lock_Functions(3); 
//        } 
//        else if (HOLD_FLAG[3] == false && function[3] > 3 && Set_Upper == true) {  //cancel the set upper function on wavetable
//          Set_Upper = false;  
//          blink_led[0] = false;
//        }
//        else if (HOLD_FLAG[3] == false && function[3] < 4 && Set_Upper == true) {        
//          swnum = 9; 
//          if (Save_Upper[3] == false) {  //upper offset first time through to select channel
//            Serial2.print("?y3?x00?l"); 
//            Set_Upper_Offset_A(3, 4); 
//            blink_led[4] = true;
//          }
//          else {                          //second time through to save upper setting
//            Serial2.print("?y3?x00?l"); 
//            Set_Upper_Offset_B(3, 4); 
//            blink_led[4] = false;
//          }
//        }

//      case 6:   //**********lower button channel 4*************
//      Lower_Button(3,4,6);
//        if (HOLD_FLAG[3] == false && Set_Lower == false && Set_Upper == false) {       //no lock or offset functions
//          Serial2.print("?y3?x00?l");
//          Set_Functions(3, 4); 
//        }       
//        else if (HOLD_FLAG[3] == false && Set_Lower == true && function[3] > 3 ) {   //cancel set lower function on wavetable
//          Set_Lower = false;   
//          blink_led[2] = false;
//        }
//
//        else if (HOLD_FLAG[3] == false && Set_Lower == true && function[3] < 4 ) {
//          swnum = 9; 
//          if (Save_Lower[3] == false) {  //first time through to select channel
//            Serial2.print("?y3?x00?l");
//            Set_Lower_Offset_A(3, 4); 
//            blink_led[6] = true;
//          }
//          else {                          //second time through to save lower setting
//            Serial2.print("?y3?x00?l"); 
//            Set_Lower_Offset_B(3, 4); 
//            blink_led[6] = false;
//          }
//        }
//        else if (HOLD_FLAG[3] == true) {   //restore 
//          Serial2.print("?y3?x00?l");
//          Restore_Functions(3, 4); 
//        }  
//        if (HOLD_FLAG[3] == false && Set_Lower == false && Set_Upper == false) {       //no lock or offset functions
//          Serial2.print("?y3?x00?l");
//          Set_Functions(3, 4); 
//        }       
//        else if (HOLD_FLAG[3] == false && Set_Lower == true && function[3] > 3 ) {   //cancel set lower function on wavetable
//          Set_Lower = false;   
//          blink_led[2] = false;
//        }
//
//        else if (HOLD_FLAG[3] == false && Set_Lower == true && function[3] < 4 ) {
//          swnum = 9; 
//          if (Save_Lower[3] == false) {  //first time through to select channel
//            Serial2.print("?y3?x00?l");
//            Set_Lower_Offset_A(3, 4); 
//            blink_led[6] = true;
//          }
//          else {                          //second time through to save lower setting
//            Serial2.print("?y3?x00?l"); 
//            Set_Lower_Offset_B(3, 4); 
//            blink_led[6] = false;
//          }
//        }
//        else if (HOLD_FLAG[3] == true) {   //restore 
//          Serial2.print("?y3?x00?l");
//          Restore_Functions(3, 4); 
//        }  











